#include "stdafx.h"
#include "View.h"
#include "SkCanvas.h"
#include "WidgetWin.h"

View::View(View* parent)
	: m_x(0)
	, m_y(0)
	, m_width(0)
	, m_height(0)
	, m_parent(parent)
	, m_status(STATUS_NORMAL)
	, m_top_pad(0)
	, m_left_pad(0)
	, m_text(L"")
	, m_id(0xFFFFFFFF)
{
	m_childViews.clear();

	if (m_parent)
	{
		m_parent->addChild(this);
	}
}


View::~View()
{
	for (std::list<View*>::iterator iter = m_childViews.begin(); iter != m_childViews.end(); ++iter)
	{
		if (*iter)
		{
			delete *iter;
			*iter = NULL;
		}
	}

	m_childViews.clear();
}

void View::setBolder(unsigned int x, unsigned int y, unsigned int width, unsigned int height)
{
	m_x = x;
	m_y = y;
	m_width = width;
	m_height = height;
}

unsigned int View::X()
{
	return m_x;
}

unsigned int View::Y()
{
	return m_y;
}

unsigned int View::Width()
{
	return m_width;
}

unsigned int View::Height()
{
	return m_height;
}

void View::setID(uint32 id)
{
	m_id = id;
}
uint32 View::getID()
{
	return m_id;
}


bool View::updateLayout()
{
	return false;
}

bool View::addChild(View* view)
{
	if (view == NULL)
	{
		return false;
	}

	m_childViews.push_back(view);

	return true;
}

bool View::remoteChild(View* view)
{
	if (view == NULL)
	{
		return false;
	}

	for (std::list<View*>::iterator iter = m_childViews.begin(); iter != m_childViews.end(); ++iter)
	{
		if (*iter == view)
		{
			m_childViews.erase(iter);
			return true;
		}
	}

	return false;
}

void View::setStatus(uint32 status)
{
	if (m_status != status)
	{
		m_status = status;

		// ATLTRACE("[%s] this: 0x%X, m_status: %d\r\n", __FUNCTION__, this, m_status);

		//TODO: this function can't be used in here.
		updateView();
	}
}

uint32 View::getStatus()
{
	return m_status;
}

void View::setParent(View* parent)
{
	m_parent = parent;
}

View* View::getParent()
{
	return m_parent;
}


bool View::onPaint(SkCanvas* canvas)
{
	// ATLTRACE("[%s] this: 0x%X, m_status: %d\r\n", __FUNCTION__, this, m_status);

	canvas->save();

	if (canvas->clipRect(X(), Y(), Width(), Height()))
	{
		canvas->translate(X(), Y());
		{
			paint(canvas);

			for (std::list<View*>::iterator iter = m_childViews.begin(); iter != m_childViews.end(); ++iter)
			{
				if (*iter)
				{
					(*iter)->onPaint(canvas);
				}
			}

		}
	}

	canvas->restore();

	return true;
}

void View::mouseEntry()
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);
}

void View::mouseLeave()
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);
}

void View::gotFocus()
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);
}

void View::loseFocus()
{
	ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);
}

void View::setText(std::wstring& text)
{
	m_text = text;
}

std::wstring View::getText()
{
	return m_text;
}

bool View::paint(SkCanvas* canvas)
{
	if (canvas == NULL)
	{
		ATLTRACE("[%s][%d]\r\n", __FUNCTION__, __LINE__);
		return false;
	}

	if (canvas)
	{
		canvas->FillRect(SkColor(0, 0, 0), 0, 0, m_width, m_height);  // black
	}

	paintBorder(canvas);

	return true;
}

bool View::paintBorder(SkCanvas* canvas)
{
	if (canvas)
	{
		canvas->drawRect(SkColor(98, 192, 255, 80), 0, 0, Width() - 1, Height() - 1);
		return true;
	}

	return false;
}

bool View::paintFocus(SkCanvas* canvas)
{
	if (canvas)
	{
		canvas->drawRect(SkColor(98, 192, 255), 0, 0, Width() - 1, Height() - 1);
		return true;
	}

	return false;
}

bool View::processKeyEvent(KeyEvent& event)
{
	return true;
}

bool View::processRawKeyEvent(KeyEvent& event)
{
	return true;
}


bool View::processMouseEvent(MouseEvent& event)
{
	return true;
}


View* View::FindTopViewInPoint(int x, int y)
{
	for (std::list<View*>::iterator iter = m_childViews.begin(); iter != m_childViews.end(); ++iter)
	{
		if (*iter)
		{
			View* topView = (*iter)->FindTopViewInPoint(x, y);
			if (topView!=NULL)
			{
				return topView;
			}
		}
	}

	if (m_x < x && x < m_x + m_width
		&& m_y < y && y< m_y + m_height)
	{
		return this;
	}

	return NULL;
}

void View::updateView()
{
	//TODO: this function can't be used in here.
	RECT rect;
	rect.left = m_x;
	rect.top = m_y;
	rect.right = m_x + m_width;
	rect.bottom = m_y + m_height;
	::InvalidateRect(GetParent(WidgetWin::getInstance().getNativeHwnd()), &rect, TRUE);
}

View* View::getViewById(uint32 id)
{
	if (getID() == id)
	{
		return this;
	}
	for (std::list<View*>::iterator iter = m_childViews.begin(); iter != m_childViews.end(); ++iter)
	{
		if (*iter)
		{
			View* view = (*iter)->getViewById(id);
			if (view != NULL)
			{
				return view;
			}
		}
	}

	return NULL;
}